package com.eedi.framework.dict.framework.dict;

import cn.hutool.core.collection.CollUtil;
import com.eedi.framework.dict.controller.sys.vo.data.SysDictDataResp;
import com.eedi.framework.dict.controller.sys.vo.data.SysDictDataSaveReq;
import com.eedi.framework.dict.dal.dataobject.SysDictTypeDO;
import com.eedi.framework.common.enums.CommonStatusEnum;
import com.eedi.framework.dict.core.DictData;
import com.eedi.framework.dict.core.DictDataApi;
import com.eedi.framework.dict.controller.sys.vo.type.SysDictTypeSaveReq;
import com.eedi.framework.dict.service.SysDictDataService;
import com.eedi.framework.dict.service.SysDictTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DictDataApiImpl implements DictDataApi {
    @Resource
    private SysDictDataService sysDictDataService;
    @Resource
    private SysDictTypeService sysDictTypeService;

    @Override
    public DictData getDictData(String dictType, Integer value) {
        return null;
    }

    @Override
    public DictData parseDictData(String dictType, String label) {
        return null;
    }

    @Override
    public void execute(Set<DictData> dictData) {
        if (CollUtil.isEmpty(dictData)) {
            return;
        }
        //根据已有的字典集检查库里的字典集
        //查看字典类型中是否有创建：
        List<SysDictTypeDO> dictTypeList = sysDictTypeService.getDictTypeList();
        Map<String, String> inserTypeMap;
        if (CollUtil.isNotEmpty(dictTypeList)) {
            inserTypeMap = new HashMap<>();
            Map<String, SysDictTypeDO> collect = dictTypeList.stream().collect(Collectors.toMap(SysDictTypeDO::getSysDictDataType, p -> p));
            Set<DictData> inserTypeList = dictData.stream().filter(d -> !collect.containsKey(d.getDictType())).collect(Collectors.toSet());
            inserTypeList.forEach(dictType -> {
                inserTypeMap.put(dictType.getDictType(), dictType.getDictName());
            });
        } else {
            inserTypeMap = new HashMap<>();
            dictData.forEach(dictType -> {
                inserTypeMap.put(dictType.getDictType(), dictType.getDictName());
            });
        }
        log.debug("查询到库中字典类型数据为{}条；过滤出{}条需要进行插入；", dictTypeList.size(), inserTypeMap.size());
        //插入未创建的字典类型
        if (CollUtil.isNotEmpty(inserTypeMap)) {
            inserTypeMap.keySet().forEach(dictType -> {
                sysDictTypeService.createDictType(new SysDictTypeSaveReq().setSysDictDataStatus(CommonStatusEnum.ENABLE)
                        .setSysDictDataType(dictType)
                        .setSysDictName(inserTypeMap.get(dictData)));
                log.debug("插入字典类型数据{}",dictData);
            });

        }
        log.debug("插入字典类型数据完成！");
        //处理字典数据
        //根据扫描出的数据查找库中的数据
        List<SysDictDataResp> dbDictDataList = sysDictDataService.getDictDataList(
                dictData
                        .stream()
                        .map(DictData::getDictType)
                        .collect(Collectors.toSet())
        );
        //组装扫描出的数据
        List<DictData> insertList = dictData.stream()
                .filter(o1 -> !dbDictDataList.stream().anyMatch(o2 -> o1.getDictType().equals(o2.getSysDictType()) && o1.getValue().equals(o2.getSysDictValue())))
                .toList();
        log.debug("查询到库中字典数据{}条，过滤出{}条需要进行插入;", dbDictDataList.size(), insertList.size());
        //开始插入字典数据
        if (CollUtil.isNotEmpty(insertList)) {
            insertList.forEach(d -> {
                sysDictDataService.createDictData(new SysDictDataSaveReq().setSysDictDataStatus(CommonStatusEnum.ENABLE)
                        .setSysDictType(d.getDictType())
                        .setSysDictLabel(d.getLabel())
                        .setSysDictValue(d.getValue()));
                log.debug("插入字典数据{}", d.getDictType());
            });
        }
        log.debug("插入字典数据完成！");

    }

    private static boolean hasIntersection(List<DictData> set1, List<SysDictDataResp> set2) {
        Set<String> collect = set2.stream().map(SysDictDataResp::getSysDictValue).collect(Collectors.toSet());
        if (CollUtil.isEmpty(collect)) {
            return false;
        }
        for (DictData obj : set1) {
            if (collect.contains(obj.getValue())) {
                return true;
            }
        }
        return false;
    }
}
